// 属性的封装
(function () {
    /*
        属性应该是不能让外界随意修改，那样数据不安全
        TS中可以在属性前加上属性修饰符，不让用户修改属性
            public  公有属性，可以在任意位胃访问（修改） 默认值
            private 私有属性，只能在类的内部才能进行修改
            protected  受包含属性，只能在当前类和子类中访问
        在类中添加方法可以被外部访问 get方法获取，set 方法设置
     */

    // 定义一个类
    class Person {
        // 关闭name外部访问
        private _name: string;
        private _age: number;
        constructor(name: string, age: number) {
            this._name = name;
            this._age = age;
        };

        /* 
            getter()  读取属性
            setter()  设置属性
                它们被称为属性的存取器
        */
        // // 设置name属性获取
        // getName() {
        //     return this._name;
        // };
        // // 设置name属性修改
        // setName(name: string) {
        //     this._name = name;
        // };
        // getAge() {
        //     return this._age;
        // }
        // setAge(age: number) {
        //     // 添加年龄判断条件
        //     if (age >= 0) {
        //         this._age = age;
        //     }
        // }


        /*
            TS中设置getter/setter方法的方式
        */

        get name() {
            console.log("get name() 被执行了");
            return this._name;
        }
        set name(name: string) {
            this._name = name;
        }
        get age() {
            return this._age;
        }
        set age(age: number) {
            if (age >= 0) {
                this._age = age;
            } else {
                alert("年龄不能小于0，请输入正确的年龄")
            }

        }



    }

    const person1 = new Person("路飞", 18);
    /* 
        现在属性是在对象中设逻的,周性可以在意的被修改，
        属性可以任意被修改将会导致对象中的数揶变得非常不交全
    */
    // person1._name = "索隆";  // 报错 属性“_name”为私有属性，只能在类“Person”中访问
    // person1._age = 20;  // 报错 属性“_age”为私有属性，只能在类“Person”中访问
    console.log(person1)

    // // console.log(person1._name)  // 报错  属性“_name”为私有属性，只能在类“Person”中访问。
    // console.log(person1.getName())
    // person1.setName("索隆");
    // console.log(person1.getName())

    // // 
    // person1.setAge(-20);
    // console.log(person1.getAge())  // 18
    // person1.setAge(20);
    // console.log(person1.getAge())  // 20

    console.log(person1.name);
    person1.age = -20;
    console.log(person1.age);  // 18
    person1.age = 20;
    console.log(person1.age);  // 20


    // 
    class A {
        // 默认为public 公有属性
        num: number;
        private aaa: string;
        // protected 只能在类中访问，实例对象无法访问
        protected bbb: String;
        constructor(num: number, aaa: string, bbb: string) {
            this.num = num;
            this.aaa = aaa;
            this.bbb = bbb;
        }
    }
    class B extends A {
        say() {
            /* 
                子类中可以使用继承的公有属性和方法，私有属性会报错
            */
            console.log(this.num);
            // console.log(this.aaa);  // 报错 属性“aaa”为私有属性，只能在类“A”中访问

            // protected 只能在类中访问，实例对象无法访问
            console.log(this.bbb);
        }
    }

    const a = new A(123, "123", "123");

    console.log(a.num);
    // console.log(a.aaa); // 报错 属性“aaa”为私有属性，只能在类“A”中访问
    // console.log(a.bbb);  // 报错 属性“bbb”受保护，只能在类“A”及其子类中访问





    class C {
        // 可以直接将属性的声明放到构造函数中，但是需要加上权限修饰符
        constructor(public name: string, public age: number) {
            // 其实就是语法糖的写法
        }
    }
    /* 等价于：
    class C {
        public name: String;
        public age: number;
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
    }
     */
    const c = new C("弗兰奇", 23);
    console.log(c)

})()
